Plugin to upload file in SharePoint integrated with CRM 2016

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xrm.Sdk;
using Microsoft.Crm.Sdk.Messages;
using System.Runtime.Serialization;
using System.Security;
using System.ServiceModel;
using Microsoft.SharePoint.Client;
using Microsoft.Xrm.Sdk.Metadata;
using Microsoft.Xrm.Sdk.Query;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace PreAnnotationPlugin
{
public class PreAnnotationCreate : IPlugin
{

public void Execute(IServiceProvider serviceProvider)
{

//Please make sure CRM and sharepoint integration Oob is completed
//This is plugin code to trigger when new annotation record has attachment created, then it uploads the file to sharepoint, even can create custom folder
//The below code reads the filename and attachment, converts to bytes, pass the data to Sharepoint and uploads via Json rest End point
//Env: CRM 2016 onpremise, Sharepoint 2013 onpremise, gac register on CRM server Microsoft.SharePoint.Client.dll, microsoft.sharepoint.client.runtime.dll, Newtonsoft.Json.dll
//make sure the Sharepoint link “http://siteurl” is working from CRM server locally

Guid contactId;
string SiteUrl = “http://siteurl”;
string spCRMDomain = “domain”;
string spCRMUsername = “username”;
string spCRMPassword = “pass”;
Guid regardingObjId = Guid.Empty;
Guid supplierid = Guid.Empty;
string supplierName = string.Empty;
Guid certificateGuid = Guid.Empty;
Guid spDocLocDefaultCertId = Guid.Empty;
string spsiteName = string.Empty;
string folderpath = “account”; //Default
string regardingObjLogicalName = string.Empty;
string CertificateName = string.Empty;
Guid spsiteId = Guid.Empty;
Guid spDocLocAccId = Guid.Empty;
Guid spDocLocCertId = Guid.Empty;
string ctfoldername = “”;
string filename = string.Empty;
string documentBody = string.Empty;

IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof (IPluginExecutionContext));
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof (IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
ITracingService tracing = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

if (context.InputParameters.Contains(“Target”) && context.InputParameters[“Target”] is Entity)
{
try
{

Entity postMessageImage = (Entity)context.PostEntityImages[“PostImage”];

//use post image and read the values of filename an document body

tracing.Trace(“Entered the PrenotePluginstep1”);
Entity entity = (Entity) context.InputParameters[“Target”];

//convert the document to bytes
byte[] documentBytes = Convert.FromBase64String(documentBody);

//Get the root spspite that is default
string spSiteFetchXml = string.Format(@”

“, SiteUrl);

EntityCollection SpSiteDefaultist = service.RetrieveMultiple(new FetchExpression(spSiteFetchXml));

if (SpSiteDefaultist.Entities.Count > 0)
{

//Default spsiteId for http://siteurl
spsiteId = SpSiteDefaultist[0].Id;

//Get the related Certificate record
if (postMessageImage.Attributes.Contains(“objectid”))
{
regardingObjId = ((EntityReference)(postMessageImage.Attributes[“objectid”])).Id;
}

if (postMessageImage.Attributes.Contains(“objectid”))
{
regardingObjLogicalName = ((EntityReference)postMessageImage.Attributes[“objectid”]).LogicalName;

if (regardingObjLogicalName == “new_customentity”)
{

string customEntityFetchXml = string.Format(@”

“, regardingObjId);

EntityCollection customEntityList =
service.RetrieveMultiple(new FetchExpression(customEntityFetchXml));

if (customEntityList.Entities.Count > 0)
{
//get the values from the querylist
}
}
}

string customEntityrecordUrl = string.Format(“{0}_{1}”, customEntityRecordName, cusotmEntityRecordId).Replace(“-“, “”).Replace(“/”, “”).Replace(“:”, “”).Replace(“.”, “”).Replace(” “, “”).ToUpper();

//Get Default Sharepoint document location for custom record
string splocationCertfetchXml = string.Format(@”

“, regardingObjId);

EntityCollection splocCertlist = service.RetrieveMultiple(new FetchExpression(splocationCertfetchXml));

if (splocCertlist.Entities.Count > 0)
{
//found the location
spDocLocCertId = splocCertlist[0].Id;
}
else
{//create the docloc for new_customEntity record

string certificateUrl = string.Format(“{0}_{1}”, customEntityRecordName, cusotmEntityRecordId).Replace(“-“, “”).Replace(“/”, “”).Replace(“:”, “”).Replace(“.”, “”).Replace(” “, “”).ToUpper();

//GetDefaultSplocation for new_customEntity record
string splocationaccountfetchXml = string.Format(@”

“, supplierid);

EntityCollection splocAccountlist = service.RetrieveMultiple(new FetchExpression(splocationaccountfetchXml));

if (splocAccountlist.Entities.Count > 0)
{
//if found get the folder name or library name
spDocLocAccId = splocAccountlist[0].Id;

//create the Sharepoint folder for the custom entity

using (ClientContext clientContext = new ClientContext(SiteUrl))
{
SecureString passWord = new SecureString();

foreach (char c in spCRMPassword.ToCharArray()) passWord.AppendChar(c);

clientContext.Credentials = new NetworkCredential(spCRMUsername, spCRMPassword, spCRMDomain); //new SharePointOnlineCredentials(crmusername, passWord);
var folder = CreateSharePointFolder(SiteUrl, spCRMUsername, spCRMPassword, (string)splocAccountlist[0].Attributes[“relativeurl”], certificateUrl);

}
}
else
{
//Create the SharePoint folder for account and new_customentity entity

string accountURL = string.Format(“{0}_{1}”, accountName, accountId).Replace(“-“, “”).Replace(“/”, “”).Replace(“:”, “”).Replace(“.”, “”).Replace(” “, “”).ToUpper();

using (clientcontext clientcontext = new clientcontext(siteurl))
{
securestring password = new securestring();

foreach (char c in spcrmpassword.tochararray()) password.appendchar(c);

clientcontext.credentials = new networkcredential(spcrmusername, spcrmpassword, spcrmdomain); //new sharepointonlinecredentials(crmusername, password);
var folder = createfolder(clientcontext.web, “organisation”, accounturl);
folderpath = folder.name;
folder = createfolder(clientcontext.web, folderpath, certificateurl);
ctfoldername = folder.name;

}
}
}
}

bool filestatus = UploadUsingRest(“http://siteurl”, “new_customentity”, documentBytes, filename);

tracing.Trace(“After UploadUsingRest”);

// throw new Exception();

}
catch (InvalidPluginExecutionException exception)
{

tracing.Trace(“Error exception” + exception.message);
throw new InvalidPluginExecutionException(exception.Message);
}

}
}

public static bool UploadUsingRest(string siteurl, string libraryName, byte[] documentBytes, string fileName)
{

// tracing.Trace(“Entered the PrenotePluginstep1”);
bool status = false;
// byte[] binary = System.IO.File.ReadAllBytes(filePath);
// string fileName = System.IO.Path.GetFileName(filePath);
string result = string.Empty;
//Url to upload file
string resourceUrl = siteurl + “/_api/web/GetFolderByServerRelativeUrl(‘” + libraryName + “‘)/Files/add(url='” + fileName + “‘,overwrite=true)”;
HttpWebRequest wreq = HttpWebRequest.Create(resourceUrl) as HttpWebRequest;
wreq.UseDefaultCredentials = false;
//credential who has edit access on document library
NetworkCredential credentials = new System.Net.NetworkCredential(“username”, “passWord”, “domain”);
wreq.Credentials = credentials;

//Get formdigest value from site
string formDigest = GetFormDigestValue(siteurl, credentials);
wreq.Headers.Add(“X-RequestDigest”, formDigest);
wreq.Method = “POST”;
wreq.Timeout = 1000000; //timeout should be large in order to upload file which are of large size
wreq.Accept = “application/json; odata=verbose”;
wreq.ContentLength = documentBytes.Length;
try
{
using (System.IO.Stream requestStream = wreq.GetRequestStream())
{
requestStream.Write(documentBytes, 0, documentBytes.Length);
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}

try
{
WebResponse wresp = wreq.GetResponse();
using (System.IO.StreamReader sr = new System.IO.StreamReader(wresp.GetResponseStream()))
{
result = sr.ReadToEnd();
status = true;
return status;
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);

}
}

private static string GetFormDigestValue(string siteurl, NetworkCredential credentials)
{
string newFormDigest = “”;
HttpWebRequest endpointRequest = (HttpWebRequest)HttpWebRequest.Create(siteurl + “/_api/contextinfo”);
endpointRequest.Method = “POST”;
endpointRequest.ContentLength = 0;
endpointRequest.Credentials = credentials;
endpointRequest.Accept = “application/json;odata=verbose”;

try
{
HttpWebResponse endpointResponse = (HttpWebResponse)endpointRequest.GetResponse();
}
catch (Exception ex)
{
throw new Exception(ex.Message);

}

try
{
WebResponse webResp = endpointRequest.GetResponse();
Stream webStream = webResp.GetResponseStream();
StreamReader responseReader = new StreamReader(webStream);
string response = responseReader.ReadToEnd();
var j = JObject.Parse(response);
var jObj = (JObject)JsonConvert.DeserializeObject(response);
foreach (var item in jObj[“d”].Children())
{
newFormDigest = item.First()[“FormDigestValue”].ToString();
}
responseReader.Close();

}
catch (Exception ex)
{

throw new Exception(ex.Message);

}

return newFormDigest;
}

private static Folder CreateFolder(Web web, string listTitle, string fullFolderUrl)
{
if (string.IsNullOrEmpty(fullFolderUrl))
throw new ArgumentNullException(“fullFolderUrl”);

var list = web.Lists.GetByTitle(listTitle);
if (list == null)
{
return null;
}
var curFolder = list.RootFolder.Folders.Add(fullFolderUrl.ToString());
web.Context.Load(curFolder);
web.Context.ExecuteQuery();
return curFolder;
}

public static string CreateSharePointFolder(string sharepointsite, string crmusername, string crmpassword, string mainfolder, string subfolder)
{
string status = string.Empty;

if (string.IsNullOrEmpty(sharepointsite) || string.IsNullOrEmpty(crmusername) || string.IsNullOrEmpty(crmpassword) || string.IsNullOrEmpty(mainfolder) || string.IsNullOrEmpty(subfolder))
return string.Empty;

try
{
using (ClientContext clientContext = new ClientContext(sharepointsite))
{
SecureString passWord = new SecureString();

foreach (char c in crmpassword.ToCharArray()) passWord.AppendChar(c);

clientContext.Credentials = new NetworkCredential(“username”, “password”, “domain”); //new SharePointOnlineCredentials(crmusername, passWord);
var folder = CreateFolder(clientContext.Web, mainfolder, subfolder);
status = folder != null ? folder.Name : string.Empty;
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);

}
return status;

return null;
}

}
}

7 thoughts on “Plugin to upload file in SharePoint integrated with CRM 2016

    1. Hi Yeah,

      Actually CRM online and SharePoint online should be more easier than premises. Should work, but only problem I may think of dll’s in GAC. Let me know if you have any problem.
      Sama.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.